package main

import (
	"context"
	"strconv"
	pb "etcd-discovery/proto"
	"fmt"
	"log"
	"net"

	"github.com/google/uuid"
	"google.golang.org/grpc"
	"etcd-discovery/pkg/discovery"
	"google.golang.org/grpc/balancer/roundrobin"
)

const (
	appID = "sv1"
	PORT  = "9010"
)

type Sv1Service struct {
	UUID      string
	sv2Client pb.Sv2ServiceClient
	sv3Client pb.Sv3ServiceClient
}

func (s *Sv1Service) Sv1Concat(ctx context.Context, r *pb.Sv1Request) (*pb.Sv1Response, error) {
	info := "sv1.Sv1Concat:"
	return &pb.Sv1Response{Response: info + ":" + s.UUID + ":" + r.Request}, nil
}

func (s *Sv1Service) Sv2Concat(ctx context.Context, r *pb.Sv1Request) (*pb.Sv1Response, error) {
	info := "sv1.Sv2Concat:"
	resp, err := s.sv2Client.Sv2Concat(ctx, &pb.Sv2Request{Request: r.Request})
	if err != nil {
		fmt.Println("sv1 call sv2 err", err)
		return nil,err
	}
	return &pb.Sv1Response{Response: info + resp.Response}, nil
}

func (s *Sv1Service) Sv3Concat(ctx context.Context, r *pb.Sv1Request) (*pb.Sv1Response, error) {
	info := "sv1.Sv3Concat:"
	resp, err := s.sv3Client.Sv3Concat(ctx, &pb.Sv3Request{Request: r.Request})
	if err != nil {
		fmt.Println("sv1 call sv3 err", err)
		return nil,err
	}
	return &pb.Sv1Response{Response: info + resp.Response}, nil
}

func main() {
	dis := discovery.New(&discovery.Config{
		Nodes: []string{
			"127.0.0.1:2379",
		},
		Prefix: "default",
		Lease: 3,
	})
	server := grpc.NewServer()
	sv1 := NewSv1Service()
	pb.RegisterSv1ServiceServer(server, sv1)

	lis, err := net.Listen("tcp", ":"+PORT)
	if err != nil {
		log.Fatalf("net.Listen err: %v", err)
	}
	dis.Register(&discovery.Instance{
		AppID: appID,
		Hostname: sv1.UUID,
		Addrs: []string{
			"grpc://" + "127.0.0.1" + ":" + PORT,
		},
		Metadata: map[string]string{
			"weight":  strconv.FormatInt(10, 10),
		},
		
	})
	server.Serve(lis)
}

func NewSv1Service() *Sv1Service {
	var sv1 Sv1Service
	uuid := uuid.New().String()
	sv1.UUID = uuid
	sv2_targer := "etcd://default/sv2"
	sv2_conn, err := grpc.DialContext(context.Background(), sv2_targer,
		[]grpc.DialOption{
			grpc.WithInsecure(),
			grpc.WithBalancerName(roundrobin.Name),
		}...)
	if err != nil {
		panic(err)
	}
	sv1.sv2Client = pb.NewSv2ServiceClient(sv2_conn)

	sv3_targer := "etcd://default/sv3"
	sv3_conn, err := grpc.DialContext(context.Background(), sv3_targer,
		[]grpc.DialOption{
			grpc.WithInsecure(),
			grpc.WithBalancerName(roundrobin.Name),
		}...)
	if err != nil {
		panic(err)
	}
	sv1.sv3Client = pb.NewSv3ServiceClient(sv3_conn)
	return &sv1
}
